package com.evan.review.anr;

/**
 * ANR(Application Not Responding，应用无响应)知识点总结
 * ANR是Android系统对应用响应能力的一种监控机制，当应用在UI线程上执行了耗时操作导致无法及时响应时，
 * 系统会弹出"应用无响应"对话框，提示用户选择"等待"或"强制关闭"应用。
 * 
 * 本文档整理了ANR相关的知识点，适用于Android开发面试（特别是字节跳动抖音部门面试）
 */
public class ANRDoc {

    /**
     * 一、ANR的触发条件及超时时长
     * 
     * 1. 输入事件(Input)分发超时：5秒
     *    主线程处理按键/触摸事件超过5秒，将触发ANR
     *    
     * 2. 广播接收器(BroadcastReceiver)执行超时：
     *    前台广播：10秒
     *    后台广播：60秒
     *    
     * 3. 服务(Service)执行超时：
     *    前台服务：20秒
     *    后台服务：200秒（前台服务的10倍）
     *    
     * 4. 内容提供者(ContentProvider)执行超时：
     *    publish过程超时：10秒
     */
    
    /**
     * 二、ANR的常见原因
     * 
     * 1. 应用层原因：
     *    - 主线程执行了耗时操作（如网络请求、大量I/O操作、复杂计算等）
     *    - 主线程等待子线程的锁，导致死锁
     *    - 主线程大量创建对象，频繁GC，导致卡顿
     *    - BroadcastReceiver、Service等组件在主线程执行耗时操作
     *    - 应用内存紧张，导致频繁内存交换，进而影响性能
     *    
     * 2. 系统原因：
     *    - CPU资源被其他进程抢占（如前台应用运行游戏等高CPU消耗应用）
     *    - 系统资源紧张，如内存不足
     *    - 系统服务(SystemServer)响应超时
     *    - Binder机制通信超时
     */
    
    /**
     * 三、ANR的底层检测机制（详细版）
     * 
     * 1. 监控机制的核心实现：
     *    Android系统中，ANR的检测主要由ActivityManagerService(AMS)负责，具体涉及以下关键类：
     *    - ActivityManagerService：负责总体调度和ANR的判定
     *    - ProcessRecord：记录进程信息
     *    - AppNotResponding：处理ANR发生后的动作
     *    
     * 2. 消息处理机制与ANR：
     *    - Android应用基于消息循环机制(Looper-Handler-MessageQueue)
     *    - 当消息被分发到主线程的MessageQueue后，若长时间未被处理，会触发ANR
     *    - 主线程的Looper.loop()方法会不断从MessageQueue取出消息并分发处理
     *    - 若某个消息处理时间过长，后续消息无法及时处理，导致ANR
     *    
     * 3. 输入事件ANR源码分析：
     *    - InputDispatcher.cpp中有一个waitForIsr方法，负责分发输入事件
     *    - 当等待超过5秒(INPUT_DISPATCH_TIMEOUT_MILLIS)，会标记应用为unresponsive
     *    - 通过本地层(native)到Java层跨进程调用，最终由AMS处理ANR
     *    
     * 4. 服务超时ANR源码分析：
     *    - ActiveServices类中的scheduleServiceTimeoutLocked方法负责启动Service超时监控
     *    - 设置一个延时消息，使用SERVICE_TIMEOUT消息类型
     *    - 如果服务在超时时间内完成，则会移除这个消息
     *    - 否则，AMS会收到超时消息并触发ANR流程
     *    - 源码中有判断前台还是后台服务的逻辑，前台20秒，后台200秒
     *    
     * 5. 广播超时ANR源码分析：
     *    - BroadcastQueue类中的setBroadcastTimeoutLocked方法负责启动广播超时监控
     *    - 设置一个延时的BROADCAST_TIMEOUT_MSG消息
     *    - 广播处理完成后会调用cancelBroadcastTimeoutLocked取消这个消息
     *    - 如果超时未取消，则触发处理ANR流程
     *    
     * 6. "埋、拆、引爆"机制的底层实现：
     *    a. 埋定时炸弹：
     *       AMS通过Handler发送一个延迟消息（如SERVICE_TIMEOUT、BROADCAST_TIMEOUT_MSG等）
     *       
     *    b. 拆炸弹：
     *       操作完成时，通过Handler的removeMessages方法移除对应的超时消息
     *       
     *    c. 引爆炸弹：
     *       如果在规定时间内没有移除延迟消息，Handler会处理该消息，调用appNotResponding方法
     *       进行ANR处理
     */
    
    /**
     * 四、ANR处理流程的底层实现
     * 
     * 1. ANR触发后的系统行为：
     *    - AMS调用appNotResponding方法开始ANR处理流程
     *    - 收集进程CPU使用、线程堆栈、内存使用等信息
     *    - 将信息写入/data/anr/traces.txt文件
     *    - 根据配置策略，显示ANR对话框或直接杀死进程
     *    
     * 2. appNotResponding方法源码分析：
     *    - 收集ProcessRecord信息
     *    - 调用ActivityManagerService的updateCpuStatsNow收集CPU信息
     *    - 调用ProcessCpuTracker分析CPU使用情况
     *    - 通过dumpStackTraces方法获取进程堆栈信息
     *    - 调用addErrorToDropBox记录错误信息
     *    - 最后根据情况调用showAnrUi显示ANR对话框
     *    
     * 3. ANR对话框的实现：
     *    - 在system_server进程中通过Handler发送消息到UI线程
     *    - 创建一个AppErrorDialog对话框
     *    - 用户可以选择"等待"或"强制关闭"
     *    - 选择"强制关闭"会调用killAppAtUsersRequest方法杀死进程
     *    
     * 4. traces.txt文件的生成机制：
     *    - 通过调用ActivityManagerService.dumpStackTraces方法
     *    - 该方法会向目标进程发送信号，使其将线程栈信息写入文件
     *    - 使用了Java层和Native层协作的机制
     *    - 最终调用debuggerd服务获取完整线程堆栈
     *    
     * 5. ANR处理的优先级策略：
     *    - 前台应用ANR：优先显示对话框，用户可以选择等待
     *    - 后台应用ANR：Android 8.0以后默认不显示对话框，直接记录并可能终止进程
     *    - 系统关键服务ANR：可能导致设备重启
     */
    
    /**
     * 五、ANR的定位与分析（深入底层）
     * 
     * 1. ANR日志详细解析：
     *    traces.txt文件各部分含义：
     *    - 文件头部：包含ANR发生的时间、进程PID、应用包名等
     *    - 线程状态：native、suspended、runnable等
     *    - 锁信息："waiting to lock"、"held by"等表示锁等待关系
     *    - 线程堆栈：每个线程的方法调用栈
     *    - JNI引用：包含Native层引用信息
     *    - CPU使用信息：包含systemCPU、appCPU、iowait等
     *    
     * 2. 线程状态分析：
     *    - RUNNABLE：线程正在运行或可运行状态，未阻塞
     *    - BLOCKED：线程因等待监视器锁而被阻塞
     *    - WAITING：线程处于无限等待状态，等待其他线程通知
     *    - TIMED_WAITING：线程处于限时等待状态
     *    - NATIVE：线程执行Native代码
     *    - SUSPENDED：线程暂停执行
     *    
     * 3. 关键堆栈信息含义：
     *    - "waiting to lock"表示线程正在等待获取锁
     *    - "held by thread X"表示锁被线程X持有
     *    - "waiting on"表示线程在等待某个条件
     *    - "sleeping"表示线程处于睡眠状态
     *    - "epoll"相关表示正在进行网络IO操作
     *    - "futex"相关多与线程同步有关
     *    
     * 4. 内核层面的ANR分析：
     *    - 使用systrace工具分析系统调用和线程调度
     *    - 分析线程优先级(nice值)和调度策略
     *    - 检查是否存在频繁的上下文切换
     *    - 分析I/O wait时间，判断是否存在I/O瓶颈
     *    - 分析中断处理时间，检查硬件驱动问题
     *    
     * 5. Watchdog机制与ANR：
     *    - Android系统中存在Watchdog机制监控系统服务
     *    - 当系统服务无响应时会触发系统ANR
     *    - 这类ANR通常在system_server进程中产生
     *    - 可能导致设备重启或系统UI无响应
     */
    
    /**
     * 六、Handler消息机制与ANR的关系
     * 
     * 1. Handler消息机制核心原理：
     *    - Android应用基于单线程消息循环模型
     *    - 主线程中Looper.loop()循环从MessageQueue取出消息并处理
     *    - Handler负责发送消息和处理消息回调
     *    - 所有UI操作必须在主线程执行
     *    
     * 2. 消息阻塞导致ANR：
     *    - 主线程的MessageQueue中如果有一个消息处理时间过长
     *    - 会导致后续所有消息延迟处理，包括输入事件
     *    - 当延迟超过阈值（5秒）时，系统判定为ANR
     *    
     * 3. 源码层面的关联：
     *    - 输入事件通过InputDispatcher分发到应用进程
     *    - 转换为Message加入MessageQueue
     *    - 通过Choreographer.getInstance().postCallback()处理UI刷新
     *    - 如果主线程被阻塞，这些消息无法及时处理
     *    
     * 4. 消息调度优先级：
     *    - Android消息机制中的Message可以设置优先级(priority)
     *    - 高优先级的消息会优先被处理
     *    - 异步消息(setAsynchronous)可以在同步屏障时被处理
     *    - 但即使是高优先级消息，如果前面有耗时消息仍会被阻塞
     *    
     * 5. 消息队列同步屏障(Sync Barrier)：
     *    - UI更新相关消息使用同步屏障机制
     *    - 通过MessageQueue.postSyncBarrier()设置屏障
     *    - 屏障后只处理异步消息，确保UI渲染优先
     *    - 但如果主线程完全阻塞，即使有同步屏障也无法避免ANR
     */
    
    /**
     * 七、Binder机制与ANR
     * 
     * 1. Binder通信原理：
     *    - Binder是Android中的IPC(进程间通信)机制
     *    - 基于Client-Server架构，通过驱动进行跨进程调用
     *    - 系统服务和应用间通信主要依赖Binder
     *    
     * 2. Binder导致ANR的常见场景：
     *    - 应用调用系统服务(AMS、WMS等)时阻塞
     *    - Binder线程池耗尽，无法处理新的请求
     *    - Binder缓冲区已满，导致线程等待
     *    - 系统服务响应慢，导致调用方等待超时
     *    
     * 3. Binder超时机制：
     *    - Binder调用默认有16秒超时限制
     *    - 超过限制会抛出TransactionTooLargeException
     *    - 主线程上的Binder调用超时会导致ANR
     *    
     * 4. Binder死锁：
     *    - A进程持有锁X并等待B进程的操作
     *    - B进程持有锁Y并通过Binder调用A进程
     *    - A进程无法响应B的请求因为主线程被阻塞
     *    - 形成死锁，最终触发ANR
     *    
     * 5. 避免Binder导致的ANR：
     *    - 不在主线程进行同步Binder调用
     *    - 使用oneway方法实现异步Binder调用
     *    - 合理设计Binder接口，避免大数据传输
     *    - 使用AIDL的异步接口设计
     */
    
    /**
     * 八、触摸事件分发与ANR
     * 
     * 1. 触摸事件的传递路径：
     *    - 硬件层：触摸屏→驱动→Linux内核
     *    - 系统层：EventHub→InputReader→InputDispatcher
     *    - 应用层：ViewRootImpl→DecorView→View层级
     *    
     * 2. InputDispatcher的超时监测：
     *    - InputDispatcher在系统进程(system_server)中运行
     *    - 通过waitForResponse方法等待应用进程处理输入事件
     *    - 设置5秒超时阈值(INPUT_DISPATCH_TIMEOUT_MILLIS)
     *    - 超时后通过AMS触发ANR流程
     *    
     * 3. 事件分发代码中的ANR检测：
     *    - frameworks/base/services/core/java/com/android/server/input/InputDispatcher.cpp
     *    - checkANR方法检查应用是否响应
     *    - 如果应用窗口长时间未处理事件，标记为unresponsive
     *    - 通过AMS执行ANR处理流程
     *    
     * 4. 事件分发优化以避免ANR：
     *    - 避免在onTouch、onClick等回调中执行耗时操作
     *    - 复杂UI层级会增加事件分发时间，注意优化
     *    - dispatchTouchEvent、onInterceptTouchEvent等方法应保持高效
     *    - 不在事件处理过程中等待耗时的同步锁
     */
    
    /**
     * 九、ANR的优化与解决方案（深入版）
     * 
     * 1. 主线程模型优化：
     *    - 异步化：使用AsyncTask、RxJava、协程等将耗时操作移至工作线程
     *    - 消息优化：合理使用Handler的post、postDelayed和postAtTime调度任务
     *    - UI渲染分离：使用RenderThread机制减轻主线程负担
     *    - 延迟初始化：使用懒加载技术，避免启动时大量同步初始化
     *    
     * 2. 锁优化策略：
     *    - 锁分离：将一个大锁拆分为多个小锁，减少锁竞争
     *    - 锁粒度：缩小同步块范围，减少锁持有时间
     *    - 避免嵌套锁：防止死锁的关键是避免嵌套获取锁
     *    - 使用并发容器：如ConcurrentHashMap替代同步的HashMap
     *    - 使用读写锁：读多写少场景下，ReadWriteLock可提高并发性
     *    
     * 3. 系统API调用优化：
     *    - ContentProvider批量操作：使用bulkInsert替代多次insert
     *    - SharedPreferences优化：不在主线程调用commit，使用apply
     *    - Bitmap处理：在工作线程解码、缩放和处理图片
     *    - 数据库操作：所有SQLite操作都应在工作线程执行
     *    - Binder优化：大数据通过ContentProvider或文件共享，而非直接Binder传递
     *    
     * 4. 线程调度与优先级：
     *    - 使用Process.setThreadPriority()设置合适的线程优先级
     *    - 主线程保持THREAD_PRIORITY_DEFAULT
     *    - 后台线程使用THREAD_PRIORITY_BACKGROUND
     *    - UI相关的工作线程可考虑THREAD_PRIORITY_DISPLAY
     *    - 注意Android 8.0+的后台执行限制
     *    
     * 5. 架构层面的优化：
     *    - 采用响应式编程模型：如MVVM+DataBinding减少UI更新代码
     *    - 事件总线：使用LiveData、Flow等代替同步回调
     *    - 组件化：减少模块间耦合，避免串行初始化
     *    - 预加载：在合适时机预先执行可能的耗时操作
     *    - 启动优化：使用延迟初始化和分步加载减少启动时间
     */
    
    /**
     * 十、ANR监控与预防系统设计
     * 
     * 1. ANR监控方案：
     *    - 主线程Looper监控：通过Looper.getMainLooper().setMessageLogging()监控消息处理时间
     *    - 看门狗机制：实现自定义Watchdog定期检测主线程状态
     *    - 主线程卡顿监控：记录dispatchMessage前后时间差，超阈值判定为卡顿
     *    - 线程状态监控：周期性dump主线程堆栈，分析是否存在潜在ANR风险
     *    
     * 2. 线上ANR收集系统：
     *    - 通过FileObserver监控/data/anr目录
     *    - 读取并解析traces.txt文件
     *    - 结合runtime CPU采样和内存信息
     *    - 构建完整ANR上下文并上报
     *    
     * 3. ANR分析平台核心功能：
     *    - 堆栈符号化：将原始堆栈转换为可读代码行
     *    - 聚合分析：按照相似堆栈模式聚合
     *    - 趋势展示：ANR发生频率和分布统计
     *    - 关联分析：与版本、机型、系统版本的关联关系
     *    - 自动分类：区分应用原因和系统原因
     *    
     * 4. StrictMode深度应用：
     *    - 自定义违规惩罚：detectCustomSlowCalls + penaltyLog
     *    - 惩罚策略组合：如penaltyDialog + penaltyDropBox
     *    - 针对特定场景：ThreadPolicy和VmPolicy分别监控线程操作和VM操作
     *    - 集成CI系统：在开发阶段自动检测潜在ANR风险
     *    
     * 5. 预防性架构设计：
     *    - 基于消息的异步架构：消息队列解耦，避免同步等待
     *    - 基于协程的响应式设计：挂起函数代替阻塞调用
     *    - 线程池隔离原则：根据业务特性设计专用线程池，避免互相影响
     *    - 熔断机制：对可能超时的操作设置熔断，防止连锁故障
     *    - 降级策略：定义关键操作超时后的降级逻辑
     */
    
    /**
     * 十一、ANR常见面试题（进阶版）
     * 
     * 1. 请详细描述Android的ANR检测机制和源码实现？
     *    答：ANR检测机制基于超时监控实现。在系统源码中，ActivityManagerService通过发送延迟消息
     *       实现监控。例如，针对Service，在ActiveServices.scheduleServiceTimeoutLocked方法中
     *       发送SERVICE_TIMEOUT消息；针对广播，在BroadcastQueue.setBroadcastTimeoutLocked中
     *       发送BROADCAST_TIMEOUT_MSG消息。当组件启动或执行完成时，会取消对应的延迟消息。如果
     *       超时后消息仍然存在，则会触发appNotResponding处理流程，收集进程状态，生成traces文件，
     *       并显示ANR对话框。底层输入事件监控则是在native层InputDispatcher.cpp中通过waitForResponse
     *       实现的。
     *    
     * 2. 一个应用发生ANR后，系统底层做了哪些事情？
     *    答：当系统检测到ANR后，执行以下流程：
     *       1) 调用AMS.appNotResponding方法开始ANR处理
     *       2) 收集当前进程CPU使用率、内存状态等信息
     *       3) 通过Process.sendSignal发送信号给目标进程，触发其dump线程堆栈
     *       4) 将收集到的信息写入/data/anr/traces.txt文件
     *       5) 记录错误信息到dropbox
     *       6) 对于前台应用，显示ANR对话框；对于后台应用，可能直接终止进程
     *       7) 根据系统配置可能触发系统服务器回收资源
     *    
     * 3. Handler消息机制与ANR有什么关系？如何从Handler角度优化ANR？
     *    答：Handler消息机制是ANR产生的核心场景之一。Android主线程基于Looper.loop()循环处理MessageQueue
     *       中的消息，包括输入事件、UI更新等。如果某个消息处理时间过长，会阻塞后续消息处理，包括输入事件，
     *       导致ANR。
     *       优化方法：
     *       1) 避免在Handler消息回调中执行耗时操作
     *       2) 使用AsyncTask或专门的工作线程处理耗时任务
     *       3) 合理使用HandlerThread创建带有消息循环的工作线程
     *       4) 使用异步消息标记(setAsynchronous)提高关键消息优先级
     *       5) 监控消息处理时间，发现超长消息进行优化
     *    
     * 4. 如何设计一个完善的ANR监控系统？
     *    答：完善的ANR监控系统应包含以下要素：
     *       1) 线上检测：通过FileObserver监控/data/anr目录，捕获系统ANR
     *       2) 主动监测：通过主线程Looper的MessageLogging监控消息处理时间
     *       3) 线程监控：周期性采样主线程堆栈信息，发现潜在阻塞
     *       4) 看门狗机制：独立线程定期检查主线程是否响应
     *       5) 数据聚合：将ANR信息与设备状态、应用状态关联
     *       6) 自动分析：按照堆栈特征自动归类ANR原因
     *       7) 预警系统：设置阈值，在ANR率超过警戒线时及时警报
     *       8) 版本关联：将ANR与代码版本、特定提交关联，便于定位问题
     *    
     * 5. 对比Android不同版本中ANR机制的变化和优化？
     *    答：Android ANR机制在不同版本中有以下变化：
     *       1) Android 8.0(O)：后台ANR不再显示对话框，减少对用户体验的干扰
     *       2) Android 9.0(P)：改进了ANR诊断信息，traces文件包含更多系统状态
     *       3) Android 10(Q)：引入App Standby Buckets，不同活跃度的应用有不同资源限制
     *       4) Android 11(R)：增强对后台应用的限制，更积极地回收资源
     *       5) Android 12(S)：改进了前台服务ANR处理，提供更详细的诊断信息
     *       6) Android 13(T)：优化了系统资源分配，降低系统ANR率
     *       
     *       总体趋势是：系统对前台应用的ANR更加宽容，对后台应用更加严格；
     *       诊断信息越来越丰富；系统越来越倾向于保证用户体验而非应用稳定性。
     */
} 